<template>
  <div class="video-audio-container">
    <div class="hero-section">
      <h1>视频音频处理工具</h1>
      <p class="subtitle">简单、高效的视频音频处理解决方案</p>
    </div>
    
    <div class="content-section">
      <div class="upload-section" :class="{ 'has-file': videoUrl }">
        <div class="upload-area" @click="triggerFileInput" 
             :class="{ 'dragging': isDragging }" 
             @dragover.prevent="isDragging = true"
             @dragleave.prevent="isDragging = false"
             @drop.prevent="handleFileDrop">
          <input type="file" @change="handleFileUpload" accept="video/*" ref="fileInput" class="hidden-input">
          <div v-if="!videoUrl" class="upload-placeholder">
            <i class="el-icon-upload"></i>
            <p>点击或拖拽视频文件到此处</p>
            <p class="upload-tip">支持的最大文件大小：100MB</p>
          </div>
          <div v-else class="preview">
            <video :src="videoUrl" controls></video>
          </div>
        </div>
      </div>

      <div class="actions-section" v-if="videoUrl">
        <el-button class="action-btn" type="primary" @click="extractAudio" :loading="processing">
          提取音频
          <span class="btn-description">将视频转换为MP3格式</span>
        </el-button>
        <el-button class="action-btn" type="primary" @click="removeAudio" :loading="processing">
          去除音频
          <span class="btn-description">生成无声视频文件</span>
        </el-button>
      </div>

      <div v-if="resultUrl" class="result-section">
        <h2>处理结果</h2>
        <div class="result-preview">
          <audio v-if="resultType === 'audio'" :src="resultUrl" controls class="audio-player"></audio>
          <video v-else :src="resultUrl" controls></video>
        </div>
        <el-button class="download-btn" type="primary" @click="downloadResult">
          下载文件
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { FFmpeg } from '@ffmpeg/ffmpeg'
import { fetchFile, toBlobURL } from '@ffmpeg/util'
import { ElMessage } from 'element-plus'

// 状态定义
const ffmpeg = new FFmpeg()
const videoUrl = ref(null)
const resultUrl = ref(null)
const resultType = ref(null)
const processing = ref(false)
const originalFile = ref(null)
const fileInput = ref(null)
const maxFileSize = 100 * 1024 * 1024 // 100MB in bytes
const error = ref('')
const loaded = ref(false)
let isDragging = ref(false)

const load = async () => {
  try {
    const baseURL = window.location.origin;
    // 修改核心文件的加载方式
    await ffmpeg.load({
      coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
      wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
      workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript')
    });
    loaded.value = true;
    console.log('FFmpeg 加载成功');
  } catch (err) {
    console.error('FFmpeg 加载错误:', err);
    error.value = '加载转换工具失败：' + err.message;
  }
};

// 文件上传处理
const handleFileUpload = (event) => {
  const file = event.target.files[0]
  if (file) {
    if (file.size > maxFileSize) {
      ElMessage.error('文件大小不能超过100MB')
      fileInput.value.value = '' // 清空输入
      return
    }
    
    // 验证文件类型
    if (!file.type.startsWith('video/')) {
      ElMessage.error('请上传视频文件')
      fileInput.value.value = ''
      return
    }

    originalFile.value = file
    videoUrl.value = URL.createObjectURL(file)
    resultUrl.value = null
  }
}

// 提取音频
const extractAudio = async () => {
  if (!videoUrl.value || !loaded.value) return
  
  try {
    processing.value = true
    // 将视频文件转换为音频
    await ffmpeg.writeFile('input.mp4', await fetchFile(originalFile.value))
    await ffmpeg.exec(['-i', 'input.mp4', '-vn', '-acodec', 'libmp3lame', 'output.mp3'])
    
    // 获取处理后的文件
    const data = await ffmpeg.readFile('output.mp3')
    const blob = new Blob([data.buffer], { type: 'audio/mp3' })
    resultUrl.value = URL.createObjectURL(blob)
    resultType.value = 'audio'
  } catch (error) {
    console.error('提取音频失败:', error)
    ElMessage.error('提取音频失败')
  } finally {
    processing.value = false
  }
}

// 移除音频
const removeAudio = async () => {
  if (!videoUrl.value || !loaded.value) return
  
  try {
    processing.value = true
    // 移除视频中的音频
    await ffmpeg.writeFile('input.mp4', await fetchFile(originalFile.value))
    await ffmpeg.exec(['-i', 'input.mp4', '-an', 'output.mp4'])
    
    // 获取处理后的文件
    const data = await ffmpeg.readFile('output.mp4')
    const blob = new Blob([data.buffer], { type: 'video/mp4' })
    resultUrl.value = URL.createObjectURL(blob)
    resultType.value = 'video'
  } catch (error) {
    console.error('移除音频失败:', error)
    ElMessage.error('移除音频失败')
  } finally {
    processing.value = false
  }
}

// 下载结果
const downloadResult = () => {
  if (!resultUrl.value) return
  
  const link = document.createElement('a')
  link.href = resultUrl.value
  link.download = resultType.value === 'audio' ? 'extracted_audio.mp3' : 'video_without_audio.mp4'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const triggerFileInput = () => {
  fileInput.value.click()
}

const handleFileDrop = (e) => {
  isDragging = false
  const file = e.dataTransfer.files[0]
  if (file) {
    handleFileUpload({ target: { files: [file] } })
  }
}

onMounted(() => {
  load()
})
</script>

<style scoped>
.video-audio-container {
  min-height: 100vh;
  background: #ffffff;
  color: #1d1d1f;
}

.hero-section {
  text-align: center;
  padding: 80px 20px;
  background: linear-gradient(to bottom, #fbfbfd, #ffffff);
}

h1 {
  font-size: 48px;
  font-weight: 600;
  margin-bottom: 16px;
  background: linear-gradient(45deg, #1d1d1f, #434344);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.subtitle {
  font-size: 24px;
  color: #86868b;
  font-weight: 400;
}

.content-section {
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 20px;
}

.upload-section {
  margin: 40px 0;
}

.upload-area {
  border: 2px dashed #86868b;
  border-radius: 20px;
  padding: 40px;
  text-align: center;
  transition: all 0.3s ease;
  cursor: pointer;
  background: #fbfbfd;
}

.upload-area:hover, .upload-area.dragging {
  border-color: #0071e3;
  background: #f5f5f7;
}

.hidden-input {
  display: none;
}

.upload-placeholder {
  color: #86868b;
}

.upload-placeholder i {
  font-size: 48px;
  margin-bottom: 16px;
}

.upload-tip {
  font-size: 14px;
  margin-top: 8px;
  color: #86868b;
}

.preview video {
  width: 100%;
  max-width: 800px;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.actions-section {
  display: flex;
  gap: 20px;
  justify-content: center;
  margin: 40px 0;
}

.action-btn {
  height: auto;
  padding: 16px 32px;
  border-radius: 12px;
  font-size: 18px;
  background: #0071e3;
  border: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: all 0.3s ease;
}

.action-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 15px rgba(0, 113, 227, 0.3);
}

.btn-description {
  font-size: 12px;
  margin-top: 4px;
  opacity: 0.8;
}

.result-section {
  text-align: center;
  margin: 60px 0;
  padding: 40px;
  background: #f5f5f7;
  border-radius: 20px;
}

.result-section h2 {
  font-size: 32px;
  margin-bottom: 30px;
  color: #1d1d1f;
}

.result-preview {
  margin: 30px 0;
}

.audio-player {
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
}

.result-preview video {
  width: 100%;
  max-width: 800px;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.download-btn {
  padding: 16px 40px;
  font-size: 18px;
  border-radius: 12px;
  background: #0071e3;
  border: none;
  transition: all 0.3s ease;
}

.download-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 15px rgba(0, 113, 227, 0.3);
}

@media (max-width: 768px) {
  h1 {
    font-size: 36px;
  }
  
  .subtitle {
    font-size: 20px;
  }
  
  .actions-section {
    flex-direction: column;
  }
  
  .action-btn {
    width: 100%;
  }
}
</style>
